import * as THREE from 'three';

/**
 * 画点
 * @param pointGroup
 * @param point
 * @param options
 * @returns {Points}
 */
export function drawPoint(pointGroup, point, options) {
	const {color, transparent, opacity, side, depthTest} = options || {};
	const material = new THREE.PointsMaterial({
		color: color || 0xFF0000,
		transparent: transparent || true,
		opacity: opacity || 1,
		side: side || THREE.FrontSide,
		depthTest: depthTest || true
	});
	//设置具有几何顶点的几何（Geometry）或缓冲区几何（BufferGeometry）设置顶点位置，看名字就知道了，一个是直接将数据保存在js里面的，另一个是保存在WebGL缓冲区内的，而且肯定保存到WebGL缓冲区内的效率更高
	const geometry = new THREE.Geometry();
	geometry.vertices.push(point);
	//使用Line方法将线初始化
	const p = new THREE.Points(geometry, material);
	p.name = 'point';
	pointGroup.add(p);
	return p;
}

/**
 * 画线
 * @param lineGroup 线添加到指定的组或者Object3D
 * @param pointList 线的点
 * @param options {color, transparent, opacity, side, depthTest, isLine}
 * @returns {Mesh} 线
 */
export function drawLine(lineGroup, pointList, options) {
	const {color, transparent, opacity, side, depthTest, isLine} = options || {};
	const material = new THREE.LineBasicMaterial({
		color: color || 0xffFF00,
		transparent: transparent || true,
		opacity: opacity || 1,
		side: side || THREE.FrontSide,
		depthTest: depthTest || true
	});
	//设置具有几何顶点的几何（Geometry）或缓冲区几何（BufferGeometry）设置顶点位置，看名字就知道了，一个是直接将数据保存在js里面的，另一个是保存在WebGL缓冲区内的，而且肯定保存到WebGL缓冲区内的效率更高
	const geometry = new THREE.Geometry();
	pointList.forEach(value => {
		geometry.vertices.push(new THREE.Vector3(...value));
	});
	//使用Line方法将线初始化
	const line = new THREE[!isLine ? 'LineLoop' : 'Line'](geometry, material);
	line.name = 'line';
	lineGroup.add(line);
	return line;
}

/**
 * 画面
 * @param faceGroup 面添加到指定的组或者Object3D
 * @param pointList 面的点
 * @param options {color, transparent, opacity, side, depthTest}
 * @returns {Mesh} 面
 */
export function drawFace(faceGroup, pointList, options) {
	const {color, transparent, opacity, side, depthTest} = options || {};
	const geometry = new THREE.Geometry();

	pointList.forEach(points => {
		geometry.vertices.push(new THREE.Vector3(...points));
	});
	const vector3 = new THREE.Vector3();
	const c = new THREE.Color(0xffffff);
	for (let i = 2; i < pointList.length; i++) geometry.faces.push(new THREE.Face3(0, i - 1, i, vector3, c, i));

	const material = new THREE.MeshBasicMaterial({
		color: color || 0xff0000,
		transparent: transparent || true,
		opacity: opacity || 1,
		side: side || THREE.FrontSide,
		depthTest: depthTest || true
	});
	const face = new THREE.Mesh(geometry, material);
	face.name = 'face';
	faceGroup.add(face);
	return face;
}

/**
 * 画面
 * @param faceGroup 面添加到指定的组或者Object3D
 * @param pointList 面的点
 * @param options {color, transparent, opacity, side, depthTest}
 * @returns {Mesh} 面
 */
export function drawConcaveFace(faceGroup, pointList, options) {
	const {color, transparent, opacity, side, depthTest} = options || {};
	// 用来创建凹包多边形的点,一定要按顺序哦
	let points = pointList || [];
	let list = [];// 用来装点位的数组

	// 将目标数组改成Vector2 这里默认去掉高度y,当然如果你喜欢可以用其他轴的
	for (let i = 0; i < points.length; i++) list.push(new THREE.Vector2(points[i][0], points[i][2]));

	// 用这些点位生成一个 Geometry
	let geometry = new THREE.ShapeGeometry(new THREE.Shape(list));

	const material = new THREE.MeshBasicMaterial({
		color: color || 0xff0000,
		transparent: transparent || true,
		opacity: opacity || .5,
		side: side || THREE.BackSide,
		depthTest: depthTest || true
	});

	// 这就是你要的多边形啦
	let face = new THREE.Mesh(geometry, material);
	face.name = 'face';
	face.rotateX(Math.PI / 2);
	faceGroup.add(face);
	face.position.setY(1);
	return face;
}

/**
 * 让模型居中
 * @param camera
 * @param model
 */
export function setModelCenter(camera, model) {
	model.updateWorldMatrix();
	const box = new THREE.Box3().setFromObject(model);
	const boxSize = box.getSize();
	const center = box.getCenter(new THREE.Vector3());
	model.translateY(-center.y);
	model.translateX(-center.x);
	model.translateZ(-center.z);
	// model.position.copy(center);
	if (boxSize.x > boxSize.y) {
		camera.position.z = boxSize.x * -1;
		camera.position.y = boxSize.x
	} else {
		camera.position.z = boxSize.y * -1;
		camera.position.y = boxSize.y
	}
	camera.lookAt(0, 0, 0);
}

export function cameraMoveLookModel(camera, model) {
	model.updateWorldMatrix()
	const box = new THREE.Box3().setFromObject(model);
	const boxSize = box.getSize();
	console.log('boxSize', boxSize)
	const center = box.getCenter(new THREE.Vector3());
	console.log('center', center)
	// camera.position.copy(center.setScalar(500))
	// camera.lookAt(model.getWorldPosition())
	const axesHelper = new THREE.AxesHelper(1000);
	axesHelper.position.copy(boxSize)
	model.parent.add(axesHelper)

}

/**
 * 透视相机和正交相机的响应式控制视图大小
 * @param renderer
 * @param camera
 * @param width
 * @param height
 */
export function canvasResize(renderer, camera, width, height) {
	if (camera.type === 'PerspectiveCamera') {
		camera.aspect = width / height;
	} else if (camera.type === 'OrthographicCamera') {
		camera.left = -width;
		camera.right = width;
		camera.top = height;
		camera.bottom = -height;
	}
	camera.updateProjectionMatrix();
	renderer.setSize(width, height, false);
}

export default {
	drawPoint,
	drawLine,
	drawFace,
	drawConcaveFace,
	setModelCenter,
	canvasResize
};

